/**
 * @file fault_data.c
 * @brief 故障事件数据模块实现
 * @details 本文件实现了104协议的故障事件数据处理功能，包括故障事件的初始化、
 *          验证、设置和获取等操作。提供完整的故障事件管理接口。
 * 
 * @author zyb
 * @date 2025-10-02
 * @version 1.0
 * 
 * @note 所有函数都遵循104协议规范，确保严格的数据处理
 * @warning 数据转换失败时应返回相应的错误码，便于上层处理
 * 
 * @see fault_data.h
 * @see protocol_types.h
 * @see error_codes.h
 */

#include "fault_data.h"
#include "../../../../../common/logs/include/logger.h"
#include <string.h>
#include <stdlib.h>

// 定义模块名称
#define LOG_MODULE_NAME "FAULT_DATA"

/* ==================== 故障事件处理函数实现 ==================== */

/**
 * @brief 初始化故障事件数据
 * @details 初始化故障事件数据结构，设置默认值。
 *          用于创建新的故障事件数据。
 * 
 * @param fault_event 故障事件数据结构指针，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 初始化成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 * 
 * @note 初始化所有字段为默认值
 * @warning 输入指针不能为NULL
 * 
 * @see validate_fault_event
 * @see init_cp56time2a
 * @see init_qds
 */
protocol_error_t init_fault_event(fault_event_data_t* fault_event) {
    LOG_DEBUG(LOG_MODULE_NAME, "初始化故障事件数据: fault_event=%p", fault_event);
    
    if (fault_event == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "初始化故障事件数据结构，大小: %zu", sizeof(fault_event_data_t));
    memset(fault_event, 0, sizeof(fault_event_data_t));
    
    /* 初始化故障时间 */
    LOG_DEBUG(LOG_MODULE_NAME, "初始化故障时间");
    protocol_error_t result = init_cp56time2a(&fault_event->fault_time);
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "初始化故障时间失败: %d", result);
        return result;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "故障时间初始化成功");
    
    /* 初始化清除时间 */
    LOG_DEBUG(LOG_MODULE_NAME, "初始化清除时间");
    result = init_cp56time2a(&fault_event->clear_time);
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "初始化清除时间失败: %d", result);
        return result;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "清除时间初始化成功");
    
    LOG_INFO(LOG_MODULE_NAME, "故障事件数据初始化完成");
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证故障事件数据
 * @details 验证故障事件数据结构的完整性和有效性。
 *          检查所有字段的有效性。
 * 
 * @param fault_event 故障事件数据结构指针，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 验证所有字段的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see init_fault_event
 * @see validate_cp56time2a
 * @see validate_qds
 */
protocol_error_t validate_fault_event(const fault_event_data_t* fault_event) {
    LOG_DEBUG(LOG_MODULE_NAME, "验证故障事件数据: fault_event=%p", fault_event);
    
    // 检查输入参数是否为空
    if (fault_event == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证故障ID */
    LOG_DEBUG(LOG_MODULE_NAME, "验证故障ID: %u", fault_event->fault_id);
    if (fault_event->fault_id == 0) {
        LOG_ERROR(LOG_MODULE_NAME, "故障ID无效: %u", fault_event->fault_id);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    /* 验证故障类型 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证故障类型: %d", fault_event->fault_type);
    if (fault_event->fault_type >= FAULT_TYPE_MAX) {
        LOG_ERROR(LOG_MODULE_NAME, "故障类型无效: %d", fault_event->fault_type);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    /* 验证故障状态 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证故障状态: %d", fault_event->status);
    if (fault_event->status >= FAULT_STATUS_MAX) {
        LOG_ERROR(LOG_MODULE_NAME, "故障状态无效: %d", fault_event->status);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    /* 验证故障等级 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证故障等级: %d", fault_event->severity);
    if (fault_event->severity >= FAULT_LEVEL_MAX) {
        LOG_ERROR(LOG_MODULE_NAME, "故障等级无效: %d", fault_event->severity);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    /* 验证故障时间 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证故障时间");
    protocol_error_t result = validate_cp56time2a(&fault_event->fault_time);
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "故障时间验证失败: %d", result);
        return result;
    }
    
    /* 验证清除时间 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证清除时间");
    result = validate_cp56time2a(&fault_event->clear_time);
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "清除时间验证失败: %d", result);
        return result;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "故障事件数据验证成功");
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 设置故障事件基本信息
 * @details 设置故障事件的基本信息，包括故障ID、故障类型、故障状态和故障等级。
 *          用于创建和配置故障事件数据。
 * 
 * @param fault_event 故障事件数据结构指针，不能为NULL
 * @param fault_id 故障ID
 * @param fault_type 故障类型
 * @param fault_status 故障状态
 * @param severity 故障严重程度
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 设置成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_INVALID_PARAM: 参数无效
 * 
 * @note 设置故障事件的基本信息
 * @warning 输入指针不能为NULL
 * 
 * @see validate_fault_event
 * @see set_fault_event_timestamp
 * @see set_fault_event_quality
 */
protocol_error_t set_fault_event_info(fault_event_data_t* fault_event, 
                                     u32 fault_id,
                                     fault_event_type_t fault_type,
                                     fault_severity_t severity,
                                     u16 affected_circuit) {
    LOG_DEBUG(LOG_MODULE_NAME, "设置故障事件基本信息: fault_event=%p, fault_id=%u, type=%d, severity=%d, circuit=%u", 
              fault_event, fault_id, fault_type, severity, affected_circuit);
    
    // 检查输入参数是否为空
    if (fault_event == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证参数 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证故障ID: %u", fault_id);
    if (fault_id == 0) {
        LOG_ERROR(LOG_MODULE_NAME, "故障ID无效: %u", fault_id);
        return PROTOCOL_ERROR_INVALID_PARAM;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "验证故障类型: %d", fault_type);
    if (fault_type >= FAULT_TYPE_MAX) {
        LOG_ERROR(LOG_MODULE_NAME, "故障类型无效: %d", fault_type);
        return PROTOCOL_ERROR_INVALID_PARAM;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "验证故障等级: %d", severity);
    if (severity >= FAULT_LEVEL_MAX) {
        LOG_ERROR(LOG_MODULE_NAME, "故障等级无效: %d", severity);
        return PROTOCOL_ERROR_INVALID_PARAM;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "验证受影响电路: %u", affected_circuit);
    if (affected_circuit == 0) {
        LOG_ERROR(LOG_MODULE_NAME, "受影响电路无效: %u", affected_circuit);
        return PROTOCOL_ERROR_INVALID_PARAM;
    }
    
    /* 设置基本信息 */
    LOG_DEBUG(LOG_MODULE_NAME, "设置故障事件基本信息");
    fault_event->fault_id = fault_id;
    fault_event->fault_type = fault_type;
    fault_event->severity = severity;
    fault_event->affected_circuit = affected_circuit;
    
    LOG_INFO(LOG_MODULE_NAME, "故障事件基本信息设置成功: ID=%u, 类型=%d, 等级=%d, 电路=%u", 
             fault_id, fault_type, severity, affected_circuit);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 设置故障事件描述
 * @details 设置故障事件的描述信息。
 *          用于添加故障事件的详细描述。
 * 
 * @param fault_event 故障事件数据结构指针，不能为NULL
 * @param description 故障描述
 * @param location 故障位置（未使用）
 * @param cause 故障原因（未使用）
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 设置成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 * 
 * @note 设置故障事件的描述信息
 * @warning 输入指针不能为NULL
 * 
 * @see set_fault_event_info
 * @see validate_fault_event
 * @see strncpy
 */
protocol_error_t set_fault_event_description(fault_event_data_t* fault_event,
                                           const char* description) {
    LOG_DEBUG(LOG_MODULE_NAME, "设置故障事件描述: fault_event=%p, description=%s", 
              fault_event, description ? description : "NULL");
    
    // 检查输入参数是否为空
    if (fault_event == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 设置故障描述 */
    if (description != NULL) {
        LOG_DEBUG(LOG_MODULE_NAME, "设置故障描述: %s", description);
        strncpy(fault_event->description, description, sizeof(fault_event->description) - 1);
        fault_event->description[sizeof(fault_event->description) - 1] = '\0';
        LOG_DEBUG(LOG_MODULE_NAME, "故障描述设置完成，长度: %zu", strlen(fault_event->description));
    } else {
        LOG_DEBUG(LOG_MODULE_NAME, "描述为空，跳过设置");
    }
    
    
    LOG_INFO(LOG_MODULE_NAME, "故障事件描述设置成功");
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 获取故障类型描述
 * @details 根据故障类型枚举值获取对应的中文描述。
 *          用于调试和日志输出。
 * 
 * @param fault_type 故障类型枚举值
 * @return 故障类型描述字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效类型返回"未知类型"
 * 
 * @see fault_event_type_t
 * @see get_fault_severity_description
 * @see get_fault_status_description
 */
const char* get_fault_type_description(fault_event_type_t fault_type) {
    LOG_DEBUG(LOG_MODULE_NAME, "获取故障类型描述: fault_type=%d", fault_type);
    
    // 根据故障类型返回对应的中文描述
    switch (fault_type) {
        case FAULT_EVENT_TYPE_SHORT_CIRCUIT:
            LOG_DEBUG(LOG_MODULE_NAME, "故障类型: 短路故障");
            LOG_INFO(LOG_MODULE_NAME, "获取故障类型描述成功: 短路故障");
            return "短路故障";
        case FAULT_EVENT_TYPE_GROUND_FAULT:
            LOG_DEBUG(LOG_MODULE_NAME, "故障类型: 接地故障");
            LOG_INFO(LOG_MODULE_NAME, "获取故障类型描述成功: 接地故障");
            return "接地故障";
        case FAULT_EVENT_TYPE_OVERLOAD:
            LOG_DEBUG(LOG_MODULE_NAME, "故障类型: 过载故障");
            LOG_INFO(LOG_MODULE_NAME, "获取故障类型描述成功: 过载故障");
            return "过载故障";
        case FAULT_EVENT_TYPE_UNDER_VOLTAGE:
            LOG_DEBUG(LOG_MODULE_NAME, "故障类型: 欠压故障");
            LOG_INFO(LOG_MODULE_NAME, "获取故障类型描述成功: 欠压故障");
            return "欠压故障";
        case FAULT_EVENT_TYPE_OVER_VOLTAGE:
            LOG_DEBUG(LOG_MODULE_NAME, "故障类型: 过压故障");
            LOG_INFO(LOG_MODULE_NAME, "获取故障类型描述成功: 过压故障");
            return "过压故障";
        case FAULT_EVENT_TYPE_FREQUENCY_ABNORMAL:
            LOG_DEBUG(LOG_MODULE_NAME, "故障类型: 频率异常故障");
            LOG_INFO(LOG_MODULE_NAME, "获取故障类型描述成功: 频率异常故障");
            return "频率异常故障";
        case FAULT_EVENT_TYPE_POWER_QUALITY:
            LOG_DEBUG(LOG_MODULE_NAME, "故障类型: 电能质量故障");
            LOG_INFO(LOG_MODULE_NAME, "获取故障类型描述成功: 电能质量故障");
            return "电能质量故障";
        case FAULT_EVENT_TYPE_COMMUNICATION:
            LOG_DEBUG(LOG_MODULE_NAME, "故障类型: 通信故障");
            LOG_INFO(LOG_MODULE_NAME, "获取故障类型描述成功: 通信故障");
            return "通信故障";
        case FAULT_EVENT_TYPE_EQUIPMENT:
            LOG_DEBUG(LOG_MODULE_NAME, "故障类型: 设备故障");
            LOG_INFO(LOG_MODULE_NAME, "获取故障类型描述成功: 设备故障");
            return "设备故障";
        case FAULT_EVENT_TYPE_OTHER:
            LOG_DEBUG(LOG_MODULE_NAME, "故障类型: 其他故障");
            LOG_INFO(LOG_MODULE_NAME, "获取故障类型描述成功: 其他故障");
            return "其他故障";
        default:
            LOG_WARN(LOG_MODULE_NAME, "未知故障类型: %d", fault_type);
            LOG_INFO(LOG_MODULE_NAME, "获取故障类型描述: 未知类型");
            return "未知类型";
    }
}

/**
 * @brief 获取故障严重程度描述
 * @details 根据故障严重程度枚举值获取对应的中文描述。
 *          用于调试和日志输出。
 * 
 * @param severity 故障严重程度枚举值
 * @return 故障严重程度描述字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效类型返回"未知等级"
 * 
 * @see fault_severity_t
 * @see get_fault_type_description
 * @see get_fault_status_description
 */
const char* get_fault_severity_description(fault_severity_t severity) {
    LOG_DEBUG(LOG_MODULE_NAME, "获取故障严重程度描述: severity=%d", severity);
    
    // 根据故障严重程度返回对应的中文描述
    switch (severity) {
        case FAULT_SEVERITY_MINOR:
            LOG_DEBUG(LOG_MODULE_NAME, "故障严重程度: 轻微故障");
            LOG_INFO(LOG_MODULE_NAME, "获取故障严重程度描述成功: 轻微故障");
            return "轻微故障";
        case FAULT_SEVERITY_MODERATE:
            LOG_DEBUG(LOG_MODULE_NAME, "故障严重程度: 中等故障");
            LOG_INFO(LOG_MODULE_NAME, "获取故障严重程度描述成功: 中等故障");
            return "中等故障";
        case FAULT_SEVERITY_MAJOR:
            LOG_DEBUG(LOG_MODULE_NAME, "故障严重程度: 严重故障");
            LOG_INFO(LOG_MODULE_NAME, "获取故障严重程度描述成功: 严重故障");
            return "严重故障";
        case FAULT_SEVERITY_CRITICAL:
            LOG_DEBUG(LOG_MODULE_NAME, "故障严重程度: 危急故障");
            LOG_INFO(LOG_MODULE_NAME, "获取故障严重程度描述成功: 危急故障");
            return "危急故障";
        default:
            LOG_WARN(LOG_MODULE_NAME, "未知故障严重程度: %d", severity);
            LOG_INFO(LOG_MODULE_NAME, "获取故障严重程度描述: 未知等级");
            return "未知等级";
    }
}

/**
 * @brief 获取故障状态描述
 * @details 根据故障状态枚举值获取对应的中文描述。
 *          用于调试和日志输出。
 * 
 * @param status 故障状态枚举值
 * @return 故障状态描述字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效类型返回"未知状态"
 * 
 * @see fault_status_t
 * @see get_fault_type_description
 * @see get_fault_severity_description
 */
const char* get_fault_status_description(fault_status_t status) {
    LOG_DEBUG(LOG_MODULE_NAME, "获取故障状态描述: status=%d", status);
    
    // 根据故障状态返回对应的中文描述
    switch (status) {
        case FAULT_STATUS_ACTIVE:
            LOG_DEBUG(LOG_MODULE_NAME, "故障状态: 故障激活");
            LOG_INFO(LOG_MODULE_NAME, "获取故障状态描述成功: 故障激活");
            return "故障激活";
        case FAULT_STATUS_CLEARED:
            LOG_DEBUG(LOG_MODULE_NAME, "故障状态: 故障清除");
            LOG_INFO(LOG_MODULE_NAME, "获取故障状态描述成功: 故障清除");
            return "故障清除";
        case FAULT_STATUS_ACKNOWLEDGED:
            LOG_DEBUG(LOG_MODULE_NAME, "故障状态: 故障确认");
            LOG_INFO(LOG_MODULE_NAME, "获取故障状态描述成功: 故障确认");
            return "故障确认";
        case FAULT_STATUS_IGNORED:
            LOG_DEBUG(LOG_MODULE_NAME, "故障状态: 故障忽略");
            LOG_INFO(LOG_MODULE_NAME, "获取故障状态描述成功: 故障忽略");
            return "故障忽略";
        default:
            LOG_WARN(LOG_MODULE_NAME, "未知故障状态: %d", status);
            LOG_INFO(LOG_MODULE_NAME, "获取故障状态描述: 未知状态");
            return "未知状态";
    }
}